namespace classifier_test
{

namespace high_order
{

class concept_cutter : public virtual virtual_object, private noncopyable
{
public:
	struct chunk
	{
		int begin, end;
		smart_ptr<validation_dataset> vdataset;
		smart_ptr<validation_classifier> vclassifier;
		double verror;
	};

	concept_cutter();
	concept_cutter(const concept_cutter& Val);
	virtual smart_ptr<concept_cutter> clone() const = 0;
	virtual void serialize(serializer& Serializer);
	virtual void initialize_options(command_line_options& Options) const;
	virtual void apply_arguments(const command_line_arguments& Args);

	virtual void set_base_classifier(classifier* Val);
	virtual void set_base_validation_dataset(validation_dataset* VDataset);
	virtual void set_data(subarray<const record* const> SetData);
	virtual void compute() = 0;
	virtual int get_chunk_count() const = 0;
	virtual const chunk& get_chunk(int I) const = 0;
	double compute_validation_error() const;
	virtual double compute_estimated_validation_error() const = 0;

protected:
	smart_ptr<classifier> BaseClassifier;
	smart_ptr<validation_dataset> BaseVDataset;
	subarray<const record* const> Data;
};

class high_order_concept_cutter : public concept_cutter
{
public:
	high_order_concept_cutter();
	high_order_concept_cutter(const high_order_concept_cutter& Val);
	smart_ptr<concept_cutter> clone() const;
	void serialize(serializer& Serializer);
	void initialize_options(command_line_options& Options) const;
	void apply_arguments(const command_line_arguments& Args);
	void compute();
	int get_chunk_count() const;
	const chunk& get_chunk(int I) const;
	double compute_estimated_validation_error() const;

private:
	int BlockSize;
	vector<chunk> Chunks;
};

}

}
